﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Evan.Common
{
    public class IPHelper
    {
        #region IP地址互转整数
        /// <summary>
        /// 将IP地址转为整数形式
        /// </summary>
        /// <returns>整数</returns>
        public static long IP2Long(IPAddress ip)
        {
            int x = 3;
            long o = 0;
            foreach (byte f in ip.GetAddressBytes())
            {
                o += (long)f << 8 * x--;
            }
            return o;
        }
        /// <summary>
        /// 将整数转为IP地址
        /// </summary>
        /// <returns>IP地址</returns>
        public static IPAddress Long2IP(long l)
        {
            byte[] b = new byte[4];
            for (int i = 0; i < 4; i++)
            {
                b[3 - i] = (byte)(l >> 8 * i & 255);
            }
            return new IPAddress(b);
        }
        #endregion

        #region 获取客户端IP
        /// <summary>
        /// 获得客户端IP
        /// </summary>
        public static string ClientIP
        {
            get
            {
                string ip;
                string[] temp;
                bool isErr = false;
                if (HttpContext.Current.Request.ServerVariables["HTTP_X_ForWARDED_For"] == null)
                    ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"].ToString();
                else
                    ip = HttpContext.Current.Request.ServerVariables["HTTP_X_ForWARDED_For"].ToString();
                if (ip.Length > 15)
                    isErr = true;
                else
                {
                    if (ip=="::1")
                    {
                        ip = "127.0.0.1";
                    }
                    temp = ip.Split('.');
                    if (temp.Length == 4)
                    {
                        for (int i = 0; i < temp.Length; i++)
                        {
                            if (temp[i].Length > 3) isErr = true;
                        }
                    }
                    else
                        isErr = true;
                }

                if (isErr)
                    return "";
                else
                    return ip;
            }
        }

        /// <summary>
        /// 获取客户端IP地址（无视代理）
        /// </summary>
        /// <returns>若失败则返回回送地址</returns>
        public static string GetHostAddress()
        {
            string userHostAddress = HttpContext.Current.Request.UserHostAddress;

            if (string.IsNullOrEmpty(userHostAddress))
            {
                userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }

            //最后判断获取是否成功，并检查IP地址的格式（检查其格式非常重要）
            if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
            {
                return userHostAddress;
            }

            if (userHostAddress == "::1")
            {
                return "127.0.0.1";
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// 检查IP地址格式
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }

        #endregion

        #region  根据客户端IP 获取归属地信息
        /// <summary>
        /// 根据IP地址 返回所在地区名称  默认客户端IP
        /// </summary>
        /// <returns></returns>
        public static string GetNameByIP()
        {
            return GetNameByIP(GetHostAddress());
        }
        /// <summary> 
        /// 根据IP地址 返回所在地区名称
        /// </summary> 
        /// <param name="strIP">IP地址</param> 
        /// <returns></returns> 
        public static string GetNameByIP(string strIP)
        {
            string strName = "";
            if (!string.IsNullOrEmpty(strIP))
            {
                try
                {
                    string ConIPData = HttpContext.Current.Server.MapPath(System.Web.Configuration.WebConfigurationManager.AppSettings["IpConfigPath"]);
                    strName = "未能加载IPLocation.dll";//IPLocation.IPLocation.IPLocate(ConIPData, strIP.Trim());
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            return strName.Trim();
        }
        /// <summary>
        /// 获取省市信息 获取省市信息  如果是国外IP 则只返回国家信息  省市 均为 未知 默认客户端IP
        /// </summary>
        /// <returns></returns>
        public static LocationData GetLocalByIP()
        {
            return GetLocalByIP(GetHostAddress());
        }
        /// <summary>
        /// 获取省市信息  如果是国外IP 则只返回国家信息  省市 均为 未知
        /// </summary>
        /// <param name="strIP"></param>
        /// <returns></returns>
        public static LocationData GetLocalByIP(string strIP)
        {
            string local = GetNameByIP(strIP);
            LocationData locationdata = new LocationData();
            if (!string.IsNullOrEmpty(local) && local.Contains("省") && local.Contains("市"))
            {
                Regex regex = new Regex(@"[\u2E80-\u9FFF]+(?=\u7701)"); //省
                locationdata.Province = regex.Match(local).ToString();
                regex = new Regex(@"(?<=\u7701)+[\u2E80-\u9FFF]+(?=\u5e02)"); //市
                locationdata.City = regex.Match(local).ToString();
                locationdata.IP = strIP;
            }
            else if (!string.IsNullOrEmpty(local))
            {
                locationdata.Country = local;
                locationdata.Province = "未知";
                locationdata.City = "未知";
                locationdata.IP = strIP;
            }
            else
            {
                locationdata.Country = "未知";
                locationdata.Province = "未知";
                locationdata.City = "未知";
                locationdata.IP = "未知";
            }
            return locationdata;
        }
        #endregion

        #region 省市实体 包含国家 默认中国
        /// <summary>
        /// 省市实体
        /// </summary>
        public class LocationData
        {
            private string _country = "中国";
            public string Country
            {
                set { _country = value; }
                get { return _country; }
            }
            public string Province { get; set; }
            public string City { get; set; }
            public string IP { get; set; }
        }
        #endregion
    }
}
